#include "zf_driver_dma.h"
#include "ScnsSmctp.h"

void dma_clock_init(DMA_Channel_TypeDef*ch)
{
    switch((uint32)ch)
    {
        case (uint32)DMA1_Channel1:
        case (uint32)DMA1_Channel2:
        case (uint32)DMA1_Channel3:
        case (uint32)DMA1_Channel4:
        case (uint32)DMA1_Channel5:
        case (uint32)DMA1_Channel6:
        case (uint32)DMA1_Channel7:RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
            break;
        case (uint32)DMA2_Channel1:
        case (uint32)DMA2_Channel2:
        case (uint32)DMA2_Channel3:
        case (uint32)DMA2_Channel4:
        case (uint32)DMA2_Channel5:
        case (uint32)DMA2_Channel6:
        case (uint32)DMA2_Channel7:
        case (uint32)DMA2_Channel8:
        case (uint32)DMA2_Channel9:
        case (uint32)DMA2_Channel10:
        case (uint32)DMA2_Channel11:RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2,ENABLE);
            break;
    }
}

void dma_finish_nvic_enable(DMA_Channel_TypeDef*ch,uint8 priority)
{
    switch((uint32)ch)
    {
        case (uint32)DMA1_Channel1:
        {
            DMA1_Channel1->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA1_Channel1_IRQn);
            interrupt_set_priority(DMA1_Channel1_IRQn,priority);
            break;
        }
        case (uint32)DMA1_Channel2:
        {
            DMA1_Channel2->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA1_Channel2_IRQn);
            interrupt_set_priority(DMA1_Channel2_IRQn,priority);
            break;
        }
        case (uint32)DMA1_Channel3:
        {
            DMA1_Channel3->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA1_Channel3_IRQn);
            interrupt_set_priority(DMA1_Channel3_IRQn,priority);
            break;
        }
        case (uint32)DMA1_Channel4:
        {
            DMA1_Channel4->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA1_Channel4_IRQn);
            interrupt_set_priority(DMA1_Channel4_IRQn,priority);
            break;
        }
        case (uint32)DMA1_Channel5:
        {
            DMA1_Channel5->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA1_Channel5_IRQn);
            interrupt_set_priority(DMA1_Channel5_IRQn,priority);
            break;
        }
        case (uint32)DMA1_Channel6:
        {
            DMA1_Channel6->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA1_Channel6_IRQn);
            interrupt_set_priority(DMA1_Channel6_IRQn,priority);
            break;
        }
        case (uint32)DMA1_Channel7:
        {
            DMA1_Channel7->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA1_Channel7_IRQn);
            interrupt_set_priority(DMA1_Channel7_IRQn,priority);
            break;
        }
        case (uint32)DMA2_Channel1:
        {
            DMA2_Channel1->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA2_Channel1_IRQn);
            interrupt_set_priority(DMA2_Channel1_IRQn,priority);
            break;
        }
        case (uint32)DMA2_Channel2:
        {
            DMA2_Channel2->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA2_Channel2_IRQn);
            interrupt_set_priority(DMA2_Channel2_IRQn,priority);
            break;
        }
        case (uint32)DMA2_Channel3:
        {
            DMA2_Channel3->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA2_Channel3_IRQn);
            interrupt_set_priority(DMA2_Channel3_IRQn,priority);
            break;
        }
        case (uint32)DMA2_Channel4:
        {
            DMA2_Channel4->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA2_Channel4_IRQn);
            interrupt_set_priority(DMA2_Channel4_IRQn,priority);
            break;
        }
        case (uint32)DMA2_Channel5:
        {
            DMA2_Channel5->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA2_Channel5_IRQn);
            interrupt_set_priority(DMA2_Channel5_IRQn,priority);
            break;
        }
        case (uint32)DMA2_Channel6:
        {
            DMA2_Channel6->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA2_Channel6_IRQn);
            interrupt_set_priority(DMA2_Channel6_IRQn,priority);
            break;
        }
        case (uint32)DMA2_Channel7:
        {
            DMA2_Channel7->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA2_Channel7_IRQn);
            interrupt_set_priority(DMA2_Channel7_IRQn,priority);
            break;
        }
        case (uint32)DMA2_Channel8:
        {
            DMA2_Channel8->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA2_Channel8_IRQn);
            interrupt_set_priority(DMA2_Channel8_IRQn,priority);
            break;
        }
        case (uint32)DMA2_Channel9:
        {
            DMA2_Channel9->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA2_Channel9_IRQn);
            interrupt_set_priority(DMA2_Channel9_IRQn,priority);
            break;
        }
        case (uint32)DMA2_Channel10:
        {
            DMA2_Channel10->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA2_Channel10_IRQn);
            interrupt_set_priority(DMA2_Channel10_IRQn,priority);
            break;
        }
        case (uint32)DMA2_Channel11:
        {
            DMA2_Channel11->CFGR|=DMA_IT_TC|DMA_IT_TE;
            interrupt_enable(DMA2_Channel11_IRQn);
            interrupt_set_priority(DMA2_Channel11_IRQn,priority);
            break;
        }
    }
}

void dma_finish_nvic_disable(DMA_Channel_TypeDef*ch)
{
    switch((uint32)ch)
    {
        case (uint32)DMA1_Channel1:
        {
            DMA1_Channel1->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA1_Channel1_IRQn);
            break;
        }
        case (uint32)DMA1_Channel2:
        {
            DMA1_Channel2->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA1_Channel2_IRQn);
            break;
        }
        case (uint32)DMA1_Channel3:
        {
            DMA1_Channel3->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA1_Channel3_IRQn);
            break;
        }
        case (uint32)DMA1_Channel4:
        {
            DMA1_Channel4->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA1_Channel4_IRQn);
            break;
        }
        case (uint32)DMA1_Channel5:
        {
            DMA1_Channel5->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA1_Channel5_IRQn);
            break;
        }
        case (uint32)DMA1_Channel6:
        {
            DMA1_Channel6->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA1_Channel6_IRQn);
            break;
        }
        case (uint32)DMA1_Channel7:
        {
            DMA1_Channel7->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA1_Channel7_IRQn);
            break;
        }
        case (uint32)DMA2_Channel1:
        {
            DMA2_Channel1->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA2_Channel1_IRQn);
            break;
        }
        case (uint32)DMA2_Channel2:
        {
            DMA2_Channel2->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA2_Channel2_IRQn);
            break;
        }
        case (uint32)DMA2_Channel3:
        {
            DMA2_Channel3->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA2_Channel3_IRQn);
            break;
        }
        case (uint32)DMA2_Channel4:
        {
            DMA2_Channel4->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA2_Channel4_IRQn);
            break;
        }
        case (uint32)DMA2_Channel5:
        {
            DMA2_Channel5->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA2_Channel5_IRQn);
            break;
        }
        case (uint32)DMA2_Channel6:
        {
            DMA2_Channel6->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA2_Channel6_IRQn);
            break;
        }
        case (uint32)DMA2_Channel7:
        {
            DMA2_Channel7->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA2_Channel7_IRQn);
            break;
        }
        case (uint32)DMA2_Channel8:
        {
            DMA2_Channel8->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA2_Channel8_IRQn);
            break;
        }
        case (uint32)DMA2_Channel9:
        {
            DMA2_Channel9->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA2_Channel9_IRQn);
            break;
        }
        case (uint32)DMA2_Channel10:
        {
            DMA2_Channel10->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA2_Channel10_IRQn);
            break;
        }
        case (uint32)DMA2_Channel11:
        {
            DMA2_Channel11->CFGR&=~(DMA_IT_TC|DMA_IT_TE);
            interrupt_disable(DMA2_Channel11_IRQn);
            break;
        }
    }
}

void dma_print(void)
{
    static const struct
    {
        uint32 addr;
        const char*name;
    }name[]={
        {.addr=gpio_idr_addr(A0),.name="PA0"},
        {.addr=gpio_idr_addr(B0),.name="PB0"},
        {.addr=gpio_idr_addr(C0),.name="PC0"},
        {.addr=gpio_idr_addr(D0),.name="PD0"},
        {.addr=gpio_idr_addr(E0),.name="PE0"},
        {.addr=(uint32)&ADC1->RDATAR,.name="ADC"},
        {.addr=(uint32)&USART1->DATAR,.name="USART1"},
        {.addr=(uint32)&USART2->DATAR,.name="USART2"},
        {.addr=(uint32)&USART3->DATAR,.name="USART3"},
        {.addr=(uint32)&UART4->DATAR,.name="UART4"},
        {.addr=(uint32)&UART5->DATAR,.name="UART5"},
        {.addr=(uint32)&UART6->DATAR,.name="UART6"},
        {.addr=(uint32)&UART7->DATAR,.name="UART7"},
        {.addr=(uint32)&UART8->DATAR,.name="UART7"},
        {.addr=(uint32)&SPI1->DATAR,.name="SPI1"},
        {.addr=(uint32)&SPI2->DATAR,.name="SPI2"},
        {.addr=(uint32)&SPI3->DATAR,.name="SPI3"},
    };
    static const DMA_Channel_TypeDef*dmaList[2][12]={
        {DMA1_Channel1,DMA1_Channel2,DMA1_Channel3,DMA1_Channel4,DMA1_Channel5,DMA1_Channel6,DMA1_Channel7,0},
        {DMA2_Channel1,DMA2_Channel2,DMA2_Channel3,DMA2_Channel4,DMA2_Channel5,DMA2_Channel6,DMA2_Channel7,DMA2_Channel8,DMA2_Channel9,DMA2_Channel10,DMA2_Channel11,0},
    };
    for(uint8 i=0;i<2;++i)
    {
        for(uint8 j=0;dmaList[i][j];++j)
        {
            if(dmaList[i][j]->CFGR)
            {
                const uint8 ms=((dmaList[i][j]->CFGR)>>8)&3;
                const uint8 ps=((dmaList[i][j]->CFGR)>>10)&3;
                const char sName[4][3]={"8","16","32","",};
                const uint8 pl=((dmaList[i][j]->CFGR)>>12)&3;
                const char plName[4][3]={"L","M","H","VH",};
                const uint8 dir=((dmaList[i][j]->CFGR)>>4)&1;
                const char dirName[4][3]={"FR","TO"};
                hxPrintfFL("DMA%d_CH%d:",i+1,j+1);
                hxPrintf(" %2s(%d)",plName[pl],pl);
                hxPrintf(" ms:%2s(%d)",sName[ms],ms);
                hxPrintf(" ps:%2s(%d)",sName[ps],ps);
                hxPrintf(" %s ",dirName[dir]);
                {
                    uint8 find=0;
                    for(int k=0;k<(sizeof name)/(sizeof name[0]);++k)
                    {
                        if(name[k].addr==dmaList[i][j]->PADDR)
                        {
                            find=1;
                            hxPrintf("%s",name[k].name);
                            break;
                        }
                    }

                    if(!find)
                    {
                        hxPrintf("%#010X",dmaList[i][j]->PADDR);
                    }
                }

                hxPrintf("\n");
            }
        }
    }

}
